# -*- coding: utf-8 -*-
"""
用户服务层
处理用户相关的业务逻辑
"""

import requests
from typing import Dict, Optional, Tuple
from flask import current_app
from app.models.user import User
from app.models.user_attribute import UserAttribute
from app.utils.wechat import decrypt_phone_number
from app import db


class UserService:
    """用户服务类"""
    
    @staticmethod
    def wechat_login(code: str) -> Tuple[bool, Dict, str]:
        """
        微信登录
        :param code: 微信登录code
        :return: (是否成功, 数据, 错误信息)
        """
        try:
            appid = current_app.config['WECHAT_APPID']
            secret = current_app.config['WECHAT_SECRET']
            
            url = f'https://api.weixin.qq.com/sns/jscode2session?appid={appid}&secret={secret}&js_code={code}&grant_type=authorization_code'
            
            response = requests.get(url)
            result = response.json()
            
            if 'errcode' in result and result['errcode'] != 0:
                return False, {}, f"微信登录失败: {result.get('errmsg', '未知错误')}"
            
            openid = result.get('openid')
            session_key = result.get('session_key')
            
            if not openid:
                return False, {}, '获取openid失败'
            
            return True, {
                'openid': openid,
                'session_key': session_key
            }, ''
            
        except Exception as e:
            current_app.logger.error(f"微信登录异常: {str(e)}")
            return False, {}, '微信登录服务异常'
    
    @staticmethod
    def get_or_create_user(openid: str, user_info: Dict = None) -> Tuple[User, bool]:
        """
        获取或创建用户
        :param openid: 微信openid
        :param user_info: 用户信息
        :return: (用户对象, 是否新用户)
        """
        user = User.query.filter_by(openid=openid).first()
        is_new_user = False
        
        if not user:
            user = User(openid=openid)
            is_new_user = True
            
            if user_info:
                user.nickname = user_info.get('nickName')
                user.avatar_url = user_info.get('avatarUrl')
                user.gender = user_info.get('gender', 0)
            
            db.session.add(user)
            db.session.flush()
        
        return user, is_new_user
    
    @staticmethod
    def bind_phone_number(user: User, session_key: str, encrypted_data: str, iv: str) -> Tuple[bool, str, str]:
        """
        绑定手机号
        :param user: 用户对象
        :param session_key: 会话密钥
        :param encrypted_data: 加密数据
        :param iv: 初始向量
        :return: (是否成功, 手机号, 错误信息)
        """
        try:
            phone_info = decrypt_phone_number(session_key, encrypted_data, iv)
            if not phone_info or 'phoneNumber' not in phone_info:
                return False, '', '手机号解密失败'
            
            phone_number = phone_info['phoneNumber']
            
            # 检查手机号是否已被其他用户绑定
            existing_user = User.query.filter_by(phone=phone_number).first()
            if existing_user and existing_user.id != user.id:
                return False, '', '该手机号已被其他账号绑定'
            
            user.phone = phone_number
            
            # 如果是新用户且没有设置昵称，使用手机号作为默认昵称
            if not user.nickname:
                user.nickname = f"用户{phone_number[-4:]}"
            
            db.session.commit()
            return True, phone_number, ''
            
        except Exception as e:
            current_app.logger.error(f"绑定手机号异常: {str(e)}")
            db.session.rollback()
            return False, '', '绑定手机号失败'
    
    @staticmethod
    def update_user_info(user: User, data: Dict) -> bool:
        """
        更新用户信息
        :param user: 用户对象
        :param data: 更新数据
        :return: 是否成功
        """
        try:
            if 'nickname' in data:
                user.nickname = data['nickname']
            if 'avatar_url' in data:
                user.avatar_url = data['avatar_url']
            if 'gender' in data:
                user.gender = data['gender']
            
            # 更新用户属性
            if 'attributes' in data:
                for key, value in data['attributes'].items():
                    attr = UserAttribute.query.filter_by(user_id=user.id, key=key).first()
                    if attr:
                        attr.value = str(value)
                    else:
                        attr = UserAttribute(user_id=user.id, key=key, value=str(value))
                        db.session.add(attr)
            
            db.session.commit()
            return True
            
        except Exception as e:
            current_app.logger.error(f"更新用户信息异常: {str(e)}")
            db.session.rollback()
            return False
    
    @staticmethod
    def get_user_statistics(user_id: int) -> Dict:
        """
        获取用户统计信息
        :param user_id: 用户ID
        :return: 统计信息
        """
        from app.models.activity import Activity
        from app.models.user_relation import UserRelation
        
        # 组织的活动数量
        organized_count = Activity.query.filter_by(organizer_id=user_id).count()
        
        # 参与的活动数量（通过订单统计）
        participated_count = db.session.query(db.func.count(db.distinct(db.Order.activity_id)))\
            .filter(db.Order.user_id == user_id)\
            .scalar() or 0
        
        # 好友数量
        friends_count = UserRelation.query.filter_by(user_id=user_id, status='accepted').count()
        
        return {
            'organized_count': organized_count,
            'participated_count': participated_count,
            'friends_count': friends_count
        } 